package com.yunti.springboot.service.impl;


import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yunti.springboot.commonenum.SemesterEnum;
import com.yunti.springboot.mapper.ElectiveSubMapper;
import com.yunti.springboot.mapper.SubItemMapper;
import com.yunti.springboot.mapper.SubjectMapper;
import com.yunti.springboot.po.ElectiveSub;
import com.yunti.springboot.po.ScoreRule;
import com.yunti.springboot.po.SubItem;
import com.yunti.springboot.po.Subject;
import com.yunti.springboot.service.SubjectService;
import com.yunti.springboot.vo.Result;
import com.yunti.springboot.vo.req.ElectionSubjectReq;
import com.yunti.springboot.vo.req.GetSubjectReq;
import com.yunti.springboot.vo.req.SubjectReq;
import com.yunti.springboot.vo.res.GetSubjectRes;
import com.yunti.springboot.vo.res.ScoreRuleRes;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class SubjectServiceImpl extends ServiceImpl<SubjectMapper, Subject> implements SubjectService {

    @Resource
    private SubItemMapper subItemMapper;

    @Resource
    private ElectiveSubMapper electiveSubMapper;

    @Resource
    private SubjectMapper subjectMapper;

    @Override
    public Result getSubjectByYear(GetSubjectReq getSubjectReq) {
        LambdaQueryWrapper<Subject> subjectLambdaQueryWrapper = new LambdaQueryWrapper<>();
        if(getSubjectReq.getYear() != null){
            subjectLambdaQueryWrapper.eq(Subject::getYear,getSubjectReq.getYear());
        }

        List<Subject> subjectList = baseMapper.selectList(subjectLambdaQueryWrapper);
        if(subjectList.size() == 0){
            return Result.success();
        }

        List<Integer> subIdList = subjectList.stream().map(Subject::getId).collect(Collectors.toList());
        LambdaQueryWrapper<SubItem> subItemLambdaQueryWrapper = new LambdaQueryWrapper<>();
        subItemLambdaQueryWrapper.in(SubItem::getSubId,subIdList);
        List<SubItem> subItemList = subItemMapper.selectList(subItemLambdaQueryWrapper);

        Map<Integer,List<SubItem>> subItemMap = subItemList.stream().collect(Collectors.groupingBy(SubItem::getSubId));

        List<GetSubjectRes> getSubjectResList = new ArrayList<>();
        for (int i = 0; i < subjectList.size(); i++) {
            GetSubjectRes getSubjectRes = new GetSubjectRes();
            BeanUtils.copyProperties(subjectList.get(i),getSubjectRes);
            getSubjectRes.setSubItemList(subItemMap.get(getSubjectRes.getId()));
            getSubjectResList.add(getSubjectRes);
        }
        return Result.success(getSubjectResList);
    }

    @Override
    public Result getSubList(ElectionSubjectReq req) {
        LambdaQueryWrapper<Subject> subjectLambdaQueryWrapper = new LambdaQueryWrapper<>();
        subjectLambdaQueryWrapper.eq(Subject::getYear, Objects.requireNonNull(SemesterEnum.getEnumBySemester(req.getSemester())).getYear());
        subjectLambdaQueryWrapper.eq(Subject::getType,req.getType());
        List<Subject> subjectList = baseMapper.selectList(subjectLambdaQueryWrapper);
        return Result.success(subjectList);
    }

    @Override
    public Result findPage(SubjectReq req) {
        if (req.getCurrent() == null) {
            req.setCurrent(1);
        }
        if (req.getSize() == null) {
            req.setSize(10);
        }
        Page<Subject> page = new Page<Subject>(req.getCurrent() , req.getSize());
        LambdaQueryWrapper<Subject> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Objects.nonNull(req.getYear()),Subject::getYear, req.getYear());
        lambdaQueryWrapper.eq(Objects.nonNull(req.getType()),Subject::getType, req.getType());
        lambdaQueryWrapper.like(StrUtil.isNotBlank(req.getName()),Subject::getName, req.getName());
        return Result.success(baseMapper.selectPage(page,lambdaQueryWrapper));
    }


    @Override
    public Result add(SubjectReq req) {
        LambdaQueryWrapper<Subject> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Subject::getYear, req.getYear());
        lambdaQueryWrapper.eq(Subject::getName, req.getName());
        if(baseMapper.selectList(lambdaQueryWrapper).size()>0){
            return Result.error("年级【"+req.getYear()+"】,项目【"+req.getName()+"】存在");
        }
        Subject subject = new Subject();
        BeanUtils.copyProperties(req,subject);
        if(baseMapper.insert(subject)>0){
            return Result.success("添加成功");
        }
        return Result.error("添加失败");
    }

    @Override
    public Result edit(SubjectReq req) {
        LambdaQueryWrapper<Subject> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Subject::getYear, req.getYear());
        lambdaQueryWrapper.eq(Subject::getName, req.getName());
        lambdaQueryWrapper.ne(Subject::getId, req.getId());
        if(baseMapper.selectList(lambdaQueryWrapper).size()>0){
            return Result.error("年级【"+req.getYear()+"】,项目【"+req.getName()+"】存在");
        }
        Subject subject = new Subject();
        BeanUtils.copyProperties(req,subject);
        if(baseMapper.updateById(subject)>0){
            return Result.success("更新成功");
        }
        return Result.error("更新失败");
    }

    @Override
    public Result del(SubjectReq req) {
        LambdaQueryWrapper<SubItem> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SubItem::getSubId, req.getId());
        if(subItemMapper.selectList(lambdaQueryWrapper).size()>0){
            return Result.error("删除失败,存在子项。删除子项后重试。");
        }
        if(baseMapper.deleteById(req.getId())>0){
            return Result.success("删除成功");
        }
        return Result.error("删除失败");
    }
    @Override
    public Result getAllSubBySemester(Integer semester) {
        List<ElectiveSub> electiveSubList = new ArrayList<>();
        LambdaQueryWrapper<ElectiveSub> electiveSubLambdaQueryWrapper = new LambdaQueryWrapper<>();
        electiveSubLambdaQueryWrapper.eq(ElectiveSub::getSemester,semester);
        electiveSubList = electiveSubMapper.selectList(electiveSubLambdaQueryWrapper);
        List<Integer> subIdList = electiveSubList.stream().map(ElectiveSub::getSubId).collect(Collectors.toList());


        LambdaQueryWrapper<Subject> subjectLambdaQueryWrapper = new LambdaQueryWrapper<>();
        subjectLambdaQueryWrapper.in(Subject::getId,subIdList);
        if (subIdList.size() == 0){
            return Result.success(new ArrayList<>());
        }
        List<Subject> subjects = subjectMapper.selectList(subjectLambdaQueryWrapper);


        List<Integer> selectSubTypeList = electiveSubList.stream().filter(electiveSub -> electiveSub.getType()==2 || electiveSub.getType()==3).map(ElectiveSub::getType).collect(Collectors.toList());
        if(selectSubTypeList.size() > 0){
            SemesterEnum semesterEnum = SemesterEnum.getEnumBySemester(semester);
            LambdaQueryWrapper<Subject> subjectLambdaQueryWrapper2 = new LambdaQueryWrapper<>();
            subjectLambdaQueryWrapper2.eq(Subject::getYear,semesterEnum.getYear());
            subjectLambdaQueryWrapper2.in(Subject::getType, selectSubTypeList);
            List<Subject> subjects2 = subjectMapper.selectList(subjectLambdaQueryWrapper2);
            subjects.addAll(subjects2);
        }

        return Result.success(subjects);
    }
}
